uniapp 获取openid 实现登录、uniapp获取微信小程序手机号、javax.crypto.BadPaddingException: pad block corrupted 您所在的位置:网站首页 uniapp 登录接口 uniapp 获取openid 实现登录、uniapp获取微信小程序手机号、javax.crypto.BadPaddingException: pad block corrupted

uniapp 获取openid 实现登录、uniapp获取微信小程序手机号、javax.crypto.BadPaddingException: pad block corrupted

2024-07-04 10:19| 来源: 网络整理| 查看: 265

获取openid流程

小程序实现登录的流程,是先通过wx.login获取code,然后再用code请求自己服务器,自己服务器拿着code去微信服务器获取openid,然后业务自定义实现登录,微信小程序登录流程图 在这里插入图片描述

uniapp实现登录与上述流程是一样的,只是对登录实现了封装,用uni.login替代了wx.login,

uni.login({ provider: 'weixin', success: function (loginRes) { //loginRes中有code,拿着code再请求自己服务器以获取openid console.log(loginRes.authResult); } });

开发者服务器拿着code,请求微信服务器auth.code2Session接口

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

js_code=JSCODE就是上文说的code, 这个接口就会返回openid、session_key。

openid 用户的身份标识,每个用户在每个公众号或者小程序中都有一个唯一openid,跨公众号/小程序时openid不相同 session_key session_key用来解密微信wx.getUserProfile获取到的微信开放数据中的加密数据(就是encryptedData字段),但因为微信调整了用户信息权限,只能 获取openid、unionid、session_key,不能再获取头像、昵称、性别、地区。 获取openid样例代码

基本流程是,小程序/公众号端使用uni.login获取到code,传到后台,后台使用appid、appsecret、code获取到openid、unionid、session_key

小程序端

uni.login可以静默执行,也就是用户无感的情况下执行。

uni.login({ //微信授权 service: 'oauth', success: function(res) { //登录的code console.log(res.code) }, fail(err) { uni.showToast({ title: '获取失败', duration: 3000, icon: 'none' }) } }); 后端 class Controller{ @Value("${mp.appid}") private String appid; @Value("${mp.appsecret}") private String appsecret; @Autowired private RestTemplate restTemplate; @PostMapping("getOpenid") public void getOpenid(String loginCode){ String code2SessionRespStr = restTemplate.getForObject("https://api.weixin.qq.com/sns/jscode2session?appid={APPID}&secret={SECRET}&js_code={JSCODE}&grant_type=authorization_code", String.class, appid, appsecret, loginCode); } WxCode2SessionResp code2SessionResp = JSONObject.parseObject(code2SessionRespStr,WxCode2SessionResp.class); } public class WxCode2SessionResp { private String openid;// string 用户唯一标识 private String session_key;// string 会话密钥 private String unionid;// string 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回,详见 UnionID 机制说明。 private String errcode;// number 错误码 private String errmsg;// string 错误信息 }

注意,如果是双卡手机,两个手机号的openid是相同的。

小程序获取手机号

微信公众号没有获取手机号的api,似乎可以通过卡券之类的途径间接得到手机号,但总归很麻烦;小程序提供了获取手机号api,流程是前端通过用户授权获取到code,后台通过先获取access_token,再根据access_token、code获取手机号;样例代码

小程序端代码

获取手机号不能静默执行,必须由用户授权,所以有个按钮,由用户点击触发,因为api升级原因,存在低版本不支持情况,所以增加了提示。

微信授权登录 //获取用户手机号码 onGetphone(e) { console.log("获取手机号回调参数",e) if (e.detail.errMsg == 'getPhoneNumber:ok') { console.log('用户点击了接受'); //获取手机号的code const {detail:{code:getPhoneCode}} = e if(!getPhoneCode){ uni.showToast({ title:"微信版本过低,请升级", duration: 3000, icon: 'none' }) return } //发送ajax请求,将code提交到后台 } }, 后端代码 class Controller{ @Value("${mp.appid}") private String appid; @Value("${mp.appsecret}") private String appsecret; @Autowired private RestTemplate restTemplate; @PostMapping("getPhone") public void getPhone(String getPhoneCode){ String wxAccessTokenRespStr = restTemplate .getForObject("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={appsecret}", String.class, appid, appsecret); log.info("获取小程序accessToken返回值是:{}", wxAccessTokenRespStr); GetWxAccessTokenResp wxAccessTokenResp = JSONObject.parseObject(wxAccessTokenRespStr,GetWxAccessTokenResp.class); Assert.hasText(wxAccessTokenResp.getAccess_token(), wxAccessTokenResp.getErrmsg()); String access_token = wxAccessTokenResp.getAccess_token(); GetWxPhoneCommand getWxPhoneCommand = new GetWxPhoneCommand(); getWxPhoneCommand.setCode(getPhoneCode); String getWxPhoneRespStr = restTemplate .postForObject("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={ACCESS_TOKEN}", getWxPhoneCommand, String.class, access_token); log.info("获取小程序手机号返回值是:{}", getWxPhoneRespStr); GetWxPhoneResp getWxPhoneResp = JSONObject.parseObject(getWxPhoneRespStr,GetWxPhoneResp.class); public class GetWxAccessTokenResp { private String access_token;// string 获取到的凭证 private String expires_in;// number 凭证有效时间,单位:秒。目前是7200秒之内的值。 private String errCode;// number 错误码 private String errmsg;// string 错误信息 } public class GetWxPhoneCommand { private String code; } public class GetWxPhoneResp { private String errcode;// number 错误码 private String errmsg;// string 错误提示信息 private PhoneInfo phoneInfo;// Object 用户手机号信息 public static class PhoneInfo{ private String phoneNumber;// string 用户绑定的手机号(国外手机号会有区号) private String purePhoneNumber;// string 没有区号的手机号 private String countryCode;// string 区号 private Watermark watermark;// Object 数据水印 } public static class Watermark{ private String appid;// string 小程序appid private String timestamp;// number 用户获取手机号操作的时间戳 } } 问题

在实践中,会遇到javax.crypto.BadPaddingException: pad block corrupted ,这是因为在获取手机号的回调中,调用uni.login,uni.login会冲掉解密手机号用到的session_key,可参考会话密钥 session_key 有效性,这个问题有两个解决办法

uni.login先于获取手机号执行,比如在onShow()、created()中执行,仍然用login的code作为引子来解密手机号,缺点就是混在一起,耦合了;代码不再举例;手机号code和login的code拆开,各行其是,也就是说不用uni.login的code来解密手机号回调中的encryptedData,login的code只用来获取openid;手机号的code用来获取手机号;此种方式时,可以在获取手机号回调中执行uni.login。代码就是上边的那些稍微整合一些就可以。 总结

获取login的code和获取手机号的code是两回事,不要弄混。

login的code用来获取openid,uni.login可以静默执行,用户无感知手机号的code用来获取手机号,必须由用户授权 参考 小程序对encryptedData进行解密报错javax.crypto.BadPaddingException: pad block corrupted微信小程序中获取用户手机号密文数据解密报错问题


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有